<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
import { vLoading } from 'element-plus';
import * as pdfjsLib from 'pdfjs-dist';
import { obsDownload } from '#/utils/obs';
import 'pdfjs-dist/web/pdf_viewer.css';
import { ArrowDown, ArrowUp } from '@vben/icons';
import { useUserStore } from '@vben/stores';
import { useFullscreen } from '@vueuse/core';
import { Maximize, Minimize } from '@vben/icons';

// 引入 vue-office 相关组件
import VueOfficeDocx from '@vue-office/docx';
import VueOfficeExcel from '@vue-office/excel';
import VueOfficePptx from '@vue-office/pptx';
// 引入样式
import '@vue-office/docx/lib/index.css';
import '@vue-office/excel/lib/index.css';
// 注意：vue-office pptx 组件可能不需要额外的 CSS 导入

// 引入水印包装组件
import WatermarkWrapper from '#/components/WatermarkWrapper.vue';

defineOptions({ name: 'DocumentViewer' });

const props = defineProps<{
  path: string;
}>();

// 文件类型枚举
enum FileType {
  PDF = 'pdf',
  DOCX = 'docx',
  XLSX = 'xlsx',
  XLS = 'xls',
  PPTX = 'pptx'
}

// 获取文件类型
const getFileType = (path: string): FileType | null => {
  const extension = path?.split('.').pop()?.toLowerCase();
  switch (extension) {
    case 'pdf':
      return FileType.PDF;
    case 'docx':
      return FileType.DOCX;
    case 'xlsx':
      return FileType.XLSX;
    case 'xls':
      return FileType.XLS;
    case 'pptx':
      return FileType.PPTX;
    default:
      return null;
  }
};

// 当前文件类型
const fileType = ref<FileType | null>(null);

// PDF 相关状态
const pdfLoading = ref(false);
const pdfContainer = ref<any>();
const currentPage = ref(1);
const totalPages = ref(0); // 总数量

// vue-office 相关状态
const officeLoading = ref(false);
const officeDocumentSrc = ref<string | Blob | ArrayBuffer | null>(null);

const userStore = useUserStore();
const domRef = ref<HTMLElement>();
const { isFullscreen: isDomFullscreen, toggle: toggleDom } = useFullscreen(domRef);

const watermark = computed(() => {
  const userInfo = userStore.userInfo;
  return [userInfo?.nameCn, userInfo?.idCard, userInfo?.phone]
})
let pdf: any;
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
  '#/utils/pdf.worker.min.js',
  import.meta.url,
).href;

const loadPdf = async (arraybuffer?: any, isNewPdf: boolean = false, pageNumber?: number) => {
  if (!pdfContainer.value) return;
  try {
    if (!pdf) {
      pdf = await pdfjsLib.getDocument(arraybuffer).promise;
      totalPages.value = pdf.numPages;
    }
    const renderPage = async (pageNumber: number) => {
      pdfLoading.value = true;
      const page = await pdf.getPage(pageNumber);
      const canvas = document.createElement('canvas');

      // 获取父容器的宽度来自适应大小
      const containerWidth = pdfContainer.value?.clientWidth || 800;
      const baseViewport = page.getViewport({ scale: 1 });

      // 计算适合容器宽度的缩放比例
      const containerScale = (containerWidth - 40) / baseViewport.width; // 减去40px作为边距

      // 提高分辨率和清晰度
      const devicePixelRatio = window.devicePixelRatio || 1;
      const finalScale = containerScale * devicePixelRatio;
      const scaledViewport = page.getViewport({ scale: finalScale });

      // 设置canvas的实际大小（高分辨率）
      canvas.height = scaledViewport.height;
      canvas.width = scaledViewport.width;

      // 设置canvas的显示大小（自适应父元素）
      canvas.style.height = scaledViewport.height / devicePixelRatio + 'px';
      canvas.style.width = scaledViewport.width / devicePixelRatio + 'px';
      canvas.style.maxWidth = '100%';
      canvas.style.height = 'auto';
      canvas.style.display = 'block';
      canvas.style.margin = '0 auto';

      const ctx = canvas.getContext('2d');
      if (ctx) {
        // 缩放canvas context以匹配设备像素比
        ctx.scale(devicePixelRatio, devicePixelRatio);
      }

      const renderContext: any = {
        canvasContext: ctx,
        viewport: page.getViewport({ scale: containerScale }),
      };
      await page.render(renderContext).promise;
      // 添加水印
      if (ctx) {
        ctx.save();
        ctx.globalAlpha = 0.2; // 水印透明度
        ctx.font = '20px Arial';
        ctx.fillStyle = '#000000';
        ctx.rotate(-Math.PI / 6); // 旋转角度

        // 获取水印内容
        const watermarkText = watermark.value.join(' ');

        // 计算水印文本的宽度
        const textMetrics = ctx.measureText(watermarkText);
        const textWidth = textMetrics.width;
        const textHeight = 24; // 估计的文本高度

        // 计算合适的间距
        const horizontalSpacing = textWidth + 80; // 水平间距为文本宽度加10px
        const verticalSpacing = textHeight * 6; // 垂直间距为文本高度的3倍

        // 在画布上绘制水印，使用计算出的间距
        for (let i = -scaledViewport.height; i < scaledViewport.width; i += horizontalSpacing) {
          for (let j = -scaledViewport.width; j < scaledViewport.height; j += verticalSpacing) {
            // 错开每一行的起始位置，使水印呈现交错效果
            const offsetX = (j / verticalSpacing) % 2 === 0 ? 0 : horizontalSpacing / 2;
            ctx.fillText(watermarkText, i + offsetX, j);
          }
        }
        ctx.restore();
      }
      pdfContainer.value.append(canvas);
    };

    // 如果是新PDF，加载前两页
    if (isNewPdf && arraybuffer) {
      await renderPage(1);
      if (totalPages.value > 1) {
        currentPage.value = 2;
        await renderPage(2);
      }
    } else {
      const targetPage = pageNumber || currentPage.value;
      await renderPage(targetPage);
    }
  } catch (error) {
    console.error('加载 PDF 时出错:', error);
  }
  // 只有在非新PDF且有arraybuffer时才自动翻页（用于无限滚动）
  if (arraybuffer && !isNewPdf) {
    nextPage()
  }
  pdfLoading.value = false;
};

const prevPage = () => {
  if (currentPage.value > 1) {
    currentPage.value--;

    // 获取所有已渲染的 canvas 元素
    const canvases = pdfContainer.value?.querySelectorAll('canvas');
    if (canvases && canvases.length >= currentPage.value) {
      // 滚动到上一页
      const targetCanvas = canvases[currentPage.value - 1];
      if (targetCanvas) {
        targetCanvas.scrollIntoView({ behavior: 'smooth', block: 'start' });
      }
    }
  }
};

const nextPage = () => {
  if (currentPage.value < totalPages.value) {
    currentPage.value++;
    loadPdf();
  }
};

watch(() => props.path, (path) => {
  // 检测文件类型
  fileType.value = getFileType(path);

  // 重置状态
  resetState();

  // 根据文件类型加载文档
  loadDocument();
})

const resetState = () => {
  // 重置 PDF 状态
  currentPage.value = 1;
  totalPages.value = 0;

  // 清空 PDF 容器
  if (pdfContainer.value) {
    pdfContainer.value.innerHTML = '';
  }
  // 重置 PDF 对象
  pdf = null;

  // 重置 vue-office 状态
  officeDocumentSrc.value = null;
  officeLoading.value = false;
  pdfLoading.value = false;
};

// 根据文件类型加载文档
const loadDocument = () => {
  if (!fileType.value) {
    console.error('不支持的文件类型');
    return;
  }

  switch (fileType.value) {
    case FileType.PDF:
      loadingPDF();
      break;
    case FileType.DOCX:
    case FileType.XLSX:
    case FileType.XLS:
    case FileType.PPTX:
      loadingOfficeDocument();
      break;
    default:
      console.error('不支持的文件类型:', fileType.value);
  }
};

// 加载 Office 文档
const loadingOfficeDocument = () => {
  officeLoading.value = true;
  obsDownload(
    {
      // Key: 'edu/obs-sdk-browserjs-devg.pdf', // 这里应该使用 props.path
      Key: props.path,
    },
    (err: any, result: any) => {
      if (err) {
        console.error('获取文档失败:', err);
        officeLoading.value = false;
        return;
      }

      // 根据文件类型设置不同的数据格式
      if (fileType.value === FileType.PPTX) {
        // PPT 文件直接使用 ArrayBuffer
        officeDocumentSrc.value = result.InterfaceResult.Content;
      } else if (fileType.value === FileType.DOCX) {
        // Word 文件使用 Blob，指定 MIME 类型
        const blob = new Blob([result.InterfaceResult.Content], {
          type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
        });
        officeDocumentSrc.value = blob;
      } else {
        // Excel 文件使用 Blob，指定 MIME 类型
        const blob = new Blob([result.InterfaceResult.Content], {
          type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        });
        officeDocumentSrc.value = blob;
      }
      officeLoading.value = false;
    },
  );
};

// 响应式重新渲染函数
const handleResize = async () => {
  if (pdf && pdfContainer.value) {
    // 清空容器
    pdfContainer.value.innerHTML = '';
    // 重新渲染当前已加载的页面
    const pagesToRender = Math.min(currentPage.value, totalPages.value);
    for (let i = 1; i <= pagesToRender; i++) {
      await loadPdf(null, false, i);
    }
  }
};

// 防抖函数
const debounce = (func: Function, wait: number) => {
  let timeout: NodeJS.Timeout;
  return function executedFunction(...args: any[]) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
};

const debouncedResize = debounce(handleResize, 300);

const loadingPDF = () => {
  pdfLoading.value = true;
  obsDownload(
    {
      // Key: 'edu/obs-sdk-browserjs-devg.pdf',
      Key: props.path,
    },
    (err: any, result: any) => {
      if (err) {
        console.error('获取PDF失败:', err);
        pdfLoading.value = false;
        return;
      }
      loadPdf(result.InterfaceResult.Content, true);
    },
  );
};

onMounted(() => {
  // 初始化文件类型
  fileType.value = getFileType(props.path);

  // 加载文档
  loadDocument();

  // 监听窗口大小变化
  window.addEventListener('resize', debouncedResize);
});

const load = () => {
  if (!pdfLoading.value) {
    nextPage()
  }
}

// vue-office 事件处理
const onOfficeRendered = () => {
  console.log('Office 文档渲染完成');
  officeLoading.value = false;
};

const onOfficeError = (error: any) => {
  console.error('Office 文档渲染失败:', error);
  console.error('文件类型:', fileType.value);
  console.error('数据源类型:', typeof officeDocumentSrc.value);
  console.error('数据源:', officeDocumentSrc.value);
  officeLoading.value = false;
};

onUnmounted(() => {
  // 清理资源
  if (pdfContainer.value) {
    pdfContainer.value.innerHTML = '';
    pdfContainer.value = null;
  }
  pdf = null;
  // 移除窗口大小变化监听器
  window.removeEventListener('resize', debouncedResize);
});

</script>
<template>
  <div ref="domRef" class="flex h-[100%] w-full flex-col items-center" v-loading="pdfLoading || officeLoading">

    <!-- PDF 文档渲染 -->
    <template v-if="fileType === FileType.PDF">
      <div :infinite-scroll-delay="300" v-infinite-scroll="load" :infinite-scroll-distance="30"
        style="overflow: auto; width: 100%;">
        <div ref="pdfContainer" class="w-full flex flex-col items-center"></div>
      </div>
      <div class="relative bottom-[0px] py-[10px] w-[100%] text-center bg-[#000] text-[#fff] flex justify-center">
        <ArrowUp class="icon" @click="prevPage" :disabled="currentPage === 1"></ArrowUp>
        <span class="pl-[15px] pr-[15px]">{{ currentPage }} / {{ totalPages }}</span>
        <ArrowDown class="icon" @click="nextPage" :disabled="currentPage === totalPages"></ArrowDown>
        <div class="absolute right-5 top-1/2 -translate-y-1/2 icon" @click="toggleDom">
          <Minimize v-if="isDomFullscreen" />
          <Maximize v-else />
        </div>
      </div>
    </template>

    <!-- Word 文档渲染 -->
    <WatermarkWrapper v-else-if="fileType === FileType.DOCX && officeDocumentSrc" style="height: 100%; width: 100%;">
      <VueOfficeDocx :src="officeDocumentSrc" style="height: 100%; width: 100%;" @rendered="onOfficeRendered"
        @error="onOfficeError" />
    </WatermarkWrapper>

    <!-- Excel 文档渲染 -->
    <WatermarkWrapper v-else-if="(fileType === FileType.XLSX || fileType === FileType.XLS) && officeDocumentSrc"
      style="height: 100%; width: 100%;">
      <VueOfficeExcel :src="officeDocumentSrc" style="height: 100%; width: 100%;" @rendered="onOfficeRendered"
        @error="onOfficeError" />
    </WatermarkWrapper>

    <!-- PowerPoint 文档渲染 -->
    <WatermarkWrapper v-else-if="fileType === FileType.PPTX && officeDocumentSrc" style="height: 100%; width: 100%;">
      <VueOfficePptx :src="officeDocumentSrc" style="height: 100%; width: 100%;" @rendered="onOfficeRendered"
        @error="onOfficeError" />
    </WatermarkWrapper>

    <!-- 不支持的文件类型 -->
    <div v-else class="flex items-center justify-center h-full text-gray-500">
      <p>不支持的文件类型</p>
    </div>

  </div>
</template>
<style lang="less" scoped>
.icon {
  cursor: pointer;
}
</style>
